package 多线程;

import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author : K k
 * @date : 10:52 2020/8/11]
 * ReentrantLock和condition应用 消费者问题
 * 可重入锁
 * 可重入的意思是：同一个线程，能进入多个加锁（同一把锁）的方法
 * condition是用于 被ReentrantLock锁锁住的线程之间的通信 即唤醒和阻塞
 */
public class ProduceAndConsumerBuff {
    private ReentrantLock lock = new ReentrantLock();
    //private boolean flag = false;
    private Condition condition = lock.newCondition();

    int[] product = new int[10];
    private int count=0; //产品数量
    Random random=new Random(10);

    public void produce() {
        try {
            lock.lock();
            while (count == product.length) {
                //若生产够10个则阻塞线程，让消费者消费
                condition.await();
            }
            System.out.println(Thread.currentThread().getName()+"----生产------");
            product[count]= random.nextInt();
            count++;
            System.out.println("number: " + count);
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void consumer() {
        try {
            lock.lock();
            while (count == 0) {
                //若生产够10个则阻塞线程，让消费者消费
                condition.await();
            }
            System.out.println(Thread.currentThread().getName()+"----消费------");
            System.out.println("number: " + count);
            count--;
            condition.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        Integer i1=new Integer(123);
        Integer i2=new Integer(123);
        Integer i3=123;
        Integer i4=123;
        System.out.println(i4==i3);


       /* ProduceAndConsumerBuff service=new ProduceAndConsumerBuff();
        Thread thread1 = new Thread(new producer(service),"生产者");
        Thread thread2 = new Thread(new consumer(service),"消费者");

        thread1.start();
        thread2.start();*/

    }

}

class producer implements Runnable{
    private ProduceAndConsumerBuff service;
    public producer(ProduceAndConsumerBuff service){
        this.service=service;
    }

    @Override
    public void run() {
        for (int i=0; i<100; i++){
            service.produce();
        }
    }
}

class consumer implements  Runnable{

    private ProduceAndConsumerBuff service;

    public consumer(ProduceAndConsumerBuff service){
        this.service=service;
    }

    @Override
    public void run() {
        for (int i=0; i<100; i++){
            service.consumer();
        }
    }
}
